// myInternet Functionality Checker (MIFC)
// Advanced Internet Services
// 11/15/2011


import java.io.IOException;
import java.net.DatagramSocket;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.URL;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class InternetConnectivity implements Runnable {

	ConnectionStatus internetStatus = new ConnectionStatus();
	String testURL = "http://www.google.com";
	
	public final static int MIN_PORT = 0;
	public final static int MAX_PORT = 65535;
	
	// for thread synchronization
	ResultsTable sharedTable = new ResultsTable();
	private int numTests;
	static CyclicBarrier barrier;
	private static final String INET_KEY = "connectivity";
	
	
	public InternetConnectivity(ResultsTable r, CyclicBarrier b, int n){
		sharedTable = r;
		barrier = b;
		numTests = n;
	}
	
	@Override
	public void run() {
		internetStatus = runTests(numTests);
		sharedTable.addResult(INET_KEY, internetStatus);
		try {
			barrier.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public ConnectionStatus runTests (int n) {
		
		for (int i = 0; i < n; i++){
			// run the test n times
			if (isConnected()) {
				this.internetStatus.addPassedAttempt();
			} else {
				this.internetStatus.addFailedAttempt();
			}
		}
		
		return this.internetStatus;
	}
	
	private boolean isConnected () { // check the connection
	
			URL connection;
			try {
				connection = new URL(testURL);
				connection.getContent();
			} catch (MalformedURLException e) {
				e.printStackTrace();
				System.out.println("Malformed URL");
			} catch (IOException e) {
				return false;
			}
		return true;
	}
	
	public void setURL(String url) {
		this.testURL = url; // TODO: Add URL checking
	}

	
	
	// checks if a port is available locally
	public boolean portAvailable(int port) {
		if (port < MIN_PORT || port > MAX_PORT){
			throw new IllegalArgumentException("Invalid Port: " + port);
		}
		ServerSocket tcp_sock = null;
		DatagramSocket udp_sock = null;
		
		try {
			tcp_sock = new ServerSocket(port);
			tcp_sock.setReuseAddress(true);
			udp_sock = new DatagramSocket(port);
			udp_sock.setReuseAddress(true);
			return true; // 
		} catch (IOException e) {
		} finally {
				if (udp_sock != null) {
					udp_sock.close();
				}
				if (tcp_sock != null) {
					try {
						tcp_sock.close();	
					} catch (IOException e) {
						
					}
					
				} 
			}
	
		return false;
	}
	
	
	
}
